﻿/*
* YanGant 甘特图插件
* Copyright 2011, 刘玉宏
* 2011-05-10 v1.0	编写
*/
(function ($) {
    $.fn.YanGant = function (options) {
        var gantobj, gantabletobj, gantscroll, gantbody, thisTable = null; //甘特图框架
        var defaults = {
            title: "YanGant甘特图",
            data: "", //甘特图数据
            tablewidth: "240", //table宽度
            colmModel: "", //列模型
            gantWidth: "700", //甘特图宽度
            gantHeight: "500", //甘特图高度
            chattype: "day", //数据跨度day:天 week:周
            cellwidth: "35", //时间列宽度
            expandlev: '1', //默认展开级别
            cellheight: "24", //行高
            open_img: "../../JqueryPlug/YanGant/images/minus.gif",   //展开图片
            close_img: "../../JqueryPlug/YanGant/images/plus.gif", //折叠图片
            usetip: true, //是否使用默认的任务提示信息
            isfixposition: true, //是否使用定位功能
            isResizable: true
        };
        thisTable = $(this);
        var options = $.extend(defaults, options);
        var DateMethod = {
            //格式化日期
            format: function (date, str) {
                str = str.replace(/yyyy|YYYY/, date.getFullYear());
                str = str.replace(/MM/, date.getMonth() >= 9 ? ((date.getMonth() + 1) * 1).toString() : '0' + (date.getMonth() + 1) * 1);
                str = str.replace(/dd|DD/, date.getDate() > 9 ? date.getDate().toString() : '0' + date.getDate());
                return str;
            },
            //两个日期间的天数
            daysBetween: function (start, end) {
                var OneMonth = start.substring(5, start.lastIndexOf('-'));
                var OneDay = start.substring(start.length, start.lastIndexOf('-') + 1);
                var OneYear = start.substring(0, start.indexOf('-'));
                var TwoMonth = end.substring(5, end.lastIndexOf('-'));
                var TwoDay = end.substring(end.length, end.lastIndexOf('-') + 1);
                var TwoYear = end.substring(0, end.indexOf('-'));
                var cha = ((Date.parse(OneMonth + '/' + OneDay + '/' + OneYear) - Date.parse(TwoMonth + '/' + TwoDay + '/' + TwoYear)) / 86400000);
                return Math.abs(cha);
            },
            //判断是否周末
            isWeekend: function (date) {
                return date.getDay() % 6 == 0;
            },

            //判断是否周一
            isWeekstr: function (date) {
                return date.getDay() == 1;
            },
            //日期计算
            DateAdd: function (date, strInterval, Number) {
                var dtTmp = date;
                switch (strInterval) {
                    case 's': return new Date(Date.parse(dtTmp) + (1000 * Number));

                    case 'n': return new Date(Date.parse(dtTmp) + (60000 * Number));

                    case 'h': return new Date(Date.parse(dtTmp) + (3600000 * Number));

                    case 'd': return new Date(Date.parse(dtTmp) + (86400000 * Number));

                    case 'w': return new Date(Date.parse(dtTmp) + ((86400000 * 7) * Number));

                    case 'q': return new Date(dtTmp.getFullYear(), (dtTmp.getMonth()) + Number * 3, dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds());

                    case 'm': return new Date(dtTmp.getFullYear(), (dtTmp.getMonth()) + Number, dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds());

                    case 'y': return new Date((dtTmp.getFullYear() + Number), dtTmp.getMonth(), dtTmp.getDate(), dtTmp.getHours(), dtTmp.getMinutes(), dtTmp.getSeconds());
                }
                return date;
            },
            getMonths: function (start, end) {
                start = Date.parse(start); end = Date.parse(end);
                var months = [];
                months[start.getMonth()] = [start];
                var last = start;
                while (last.compareTo(end) == -1) {
                    var next = last.clone().addDays(1);
                    if (!months[next.getMonth()]) { months[next.getMonth()] = []; }
                    months[next.getMonth()].push(next);
                    last = next;
                }
                return months;
            },
            getDays: function (year, month) {
                var days = 30
                if (month == "02")
                    days = 28
                if ((",01,03,05,07,08,10,12,").indexOf("," + month + ",") > -1)
                    days = 31
                if (month == "02" && parseInt(year) % 4 == 0 && !(parseInt(year) % 100 == 0 && !(parseInt(year) % 400 == 0)))
                    days = 29
                return days
            },
            StringToDate: function (DateStr) {
                var converted = Date.parse(DateStr);
                var myDate = new Date(converted);
                if (isNaN(myDate)) {
                    //var delimCahar = DateStr.indexOf('/')!=-1?'/':'-';
                    var arys = DateStr.split('-');
                    myDate = new Date(arys[0], --arys[1], arys[2]);
                }
                return myDate;
            },
            //获取日期为某年的第几周
            GetWeekIndex: function (datestr) {
                var dateobj = this.StringToDate(datestr);
                var firstDay = this.GetFirstWeekBegDay(dateobj.getFullYear());
                if (dateobj < firstDay) {
                    firstDay = this.GetFirstWeekBegDay(dateobj.getFullYear() - 1);
                }
                d = Math.floor((dateobj.valueOf() - firstDay.valueOf()) / 86400000);
                return Math.floor(d / 7) + 1;
            },
            //获取某年的第一天
            GetFirstWeekBegDay: function (year) {
                var tempdate = new Date(year, 0, 1);
                var temp = tempdate.getDay();
                if (temp == 1) {
                    return tempdate;
                }
                temp = temp == 0 ? 7 : temp;
                tempdate = tempdate.setDate(tempdate.getDate() + (8 - temp));
                return new Date(tempdate);
            }
        };
        var waitToggle = function (element, show, fn) {
            if (show) {
                var eo = element.offset();
                var ew = element.outerWidth();
                var eh = element.outerHeight();

                if (!element.loader) {
                    element.loader = $('<div class="Yan_loading" style="top: ' + eo.top + 'px; left: ' + eo.left + 'px; width: ' + ew + 'px; height: ' + eh + 'px;"></div>');
                }
                $('body').append(element.loader);
                setTimeout(fn, 100);
            } else {
                if (element.loader)
                    element.loader.remove();
                element.loader = null;
            }
        };
        var TaskMethod = {
            //判断任务是否有包含关系
            contains: function (arrtask, task) {
                var has = false;
                for (var i = 0; i < arrtask.length; i++) {
                    if (arrtask[i] == task) {
                        has = true;
                    }
                }
                return has;
            },
            getAllChiTask: function (Tasks, arrtask, taskid) {
                var ChiTasks = [];
                for (var i = 0; i < arrtask.length; i++) {
                    if (arrtask[i].prtaskid == taskid) {
                        Tasks.push(arrtask[i]);
                        this.getAllChiTask(Tasks, arrtask, arrtask[i].taskid)
                    }
                }
            },
            //按时间排序
            sortNumber: function (a, b) {
                return DateMethod.StringToDate(a.taskPSdate) - DateMethod.StringToDate(b.taskPSdate);
            },
            //根据任务时间获取任务所在列的左边距
            getLeft: function (TaskDate, chattype, datetype) {
                var date = TaskDate;
                switch (chattype) {
                    case 'day':
                        var taskleft = $("#GantChatBodyDiv_colnum" + date, gantbody).css("left");
                        return taskleft.substr(0, taskleft.length - 2);
                        break;
                    case 'week':

                        var daycount = 1;
                        //找到开始日期所在周的周一
                        while (!DateMethod.isWeekstr(DateMethod.StringToDate(date))) {
                            date = DateMethod.format(DateMethod.DateAdd(DateMethod.StringToDate(date), 'd', -1), "YYYY-MM-DD");
                            daycount++;
                        }
                        //如果该周一不在甘特图的时间刻度中，则找下一个周一
                        if ($("#GantChatBodyDiv_colnum" + date, gantbody).length == 0) {
                            date = DateMethod.format(DateMethod.DateAdd(DateMethod.StringToDate(date), 'd', 7), "YYYY-MM-DD");
                        }
                        var taskleft = $("#GantChatBodyDiv_colnum" + date, gantbody).css("left");
                        if (datetype == "start") {
                            //计算周刻度中天数的偏移值
                            return taskleft.substr(0, taskleft.length - 2) - (-options.cellwidth / 7 * daycount);
                        } else {
                            return taskleft.substr(0, taskleft.length - 2) - (-options.cellwidth / 7 * daycount) - options.cellwidth;
                        }
                        break;
                    case 'month':
                        return "GantChatBody_ActulTask TaskLevCss2";
                        break;
                    default:
                        var taskleft = $("#GantChatBodyDiv_colnum" + date, gantbody).css("left");
                        return taskleft.substr(0, taskleft.length - 2);
                        break;
                }
            },
            //获取任务样式
            getATaskClass: function (Task) {
                switch (Task.tasklev) {
                    case '0':
                        return "GantChatBody_ActulTask TaskLevCss0";
                        break;
                    case '1':
                        return "GantChatBody_ActulTask TaskLevCss1";
                        break;
                    case '2':
                        return "GantChatBody_ActulTask TaskLevCss2";
                        break;
                    default:
                        return "GantChatBody_ActulTask TaskLevCss0";
                        break;
                }
            }
        };
        var YanGantMethod = {
            managerData: function (data) {
                //定义存放任务的数组
                var Tasks = [];
                TaskMethod.getAllChiTask(Tasks, data.tasks.sort(TaskMethod.sortNumber), data.taskpid);
                for (var i = 0; i < Tasks.length; i++) {
                    var chitasks = [];
                    TaskMethod.getAllChiTask(chitasks, Tasks, Tasks[i].taskid);
                    var arrchilds = new Array();
                    for (m = 0; m < chitasks.length; m++) {
                        arrchilds[m] = chitasks[m].taskid;
                    }
                    Tasks[i].arrchild = arrchilds;
                }
                return Tasks;
            },
            changewl: function (w, h) {
                $("#GantBody,#YanGant,#YanTitle", thisTable).each(function () {
                    var heightnow = parseInt($(this).css("height"));
                    var widthnow = parseInt($(this).css("width"));
                    if ($(this).attr("id") === "GantBody") {
                        $(this).height(heightnow + h * 1);
                    } else if ($(this).attr("id") === "YanTitle") {
                        $(this).width(widthnow + w * 1);
                    } else {
                        $(this).width(widthnow + w * 1).height(heightnow + h * 1);
                    }
                })
            },
            //添加任务甘特图
            addGantBody: function (chattype, tasks) {
                //将一格的宽度加一（包括边框的一像素）
                var startdate = options.startdate;
                var enddate = options.enddate;
                var cellWidth = options.cellwidth * 1;
                var cellheight = options.cellheight * 1;
                var gantHeight = options.gantHeight * 1;

                var rowcount = tasks.length;
                //上半部
                var upDiv = jQuery("<div>", { "id": "headUp", "class": "GantChatHeaderDiv", "css": { "height": cellheight + "px"} });
                //下半部
                var downDiv = jQuery("<div>", { "id": "headDown", "class": "GantChatHeaderDiv", "css": { "top": cellheight + 1 + "px", "height": cellheight + "px"} });
                //甘特图内容
                gantbody = jQuery("<div>", { "id": "GantBody", "class": "GantChatBody" });

                switch (chattype) {
                    //按周
                    case 'week':
                        //获取甘特图中数据对应的所有月份
                        var months = [];
                        var date = startdate;
                        while (DateMethod.StringToDate(date.substr(0, 7) + '-01') <= DateMethod.DateAdd(DateMethod.StringToDate(enddate.substr(0, 7) + '-01'), 'y', 1)) {
                            months.push(date);
                            date = DateMethod.format(DateMethod.DateAdd(DateMethod.StringToDate(date), 'm', 1), "YYYY-MM-DD");
                        }

                        //                    //甘特图的列数
                        var alldaycount = 0;
                        var headcolumcount = 0;
                        for (var i = 0; i < months.length; i++) {
                            var daycount = DateMethod.getDays(months[i].substr(0, 4), months[i].substr(5, 2));
                            alldaycount = alldaycount + daycount;
                            for (var m = 1; m <= daycount; m++) {
                                //生产甘特图表头第二行
                                var day = m <= 9 ? '0' + m : m;
                                var datecell = months[i].substr(0, 7) + "-" + day;
                                if (DateMethod.isWeekstr(DateMethod.StringToDate(datecell))) {
                                    downDiv.append(jQuery("<div>", { "class": "GantChatHeaderDiv_cell", "css": { "width": cellWidth + "px", "height": cellheight + "px", "left": headcolumcount * (cellWidth + 1) + "px"} }).append(m));
                                    gantbody.append(jQuery("<div>", { "class": "GantChatBodyDiv_colnum", "id": "GantChatBodyDiv_colnum" + datecell, "css": { "width": cellWidth + "px", "height": (cellheight + 1) * rowcount - 1 + "px", "left": headcolumcount * (cellWidth + 1) + "px"} }));
                                    headcolumcount = headcolumcount + 1;
                                }
                            }
                        }

                        var updavleft = 0;
                        for (var i = 0; i < months.length; i++) {
                            var daycountn = DateMethod.getDays(months[i].substr(0, 4), months[i].substr(5, 2));
                            var monthwidth = 0;
                            if (i == months.length - 1) {
                                monthwidth = headcolumcount * (cellWidth + 1) - updavleft - 1;
                            }
                            else {
                                monthwidth = parseInt((headcolumcount * (cellWidth + 1)) / months.length);
                            }
                            upDiv.append(jQuery("<div>", { "class": "GantChatHeaderDiv_cell", "css": { "width": monthwidth + "px", "height": cellheight + "px", "left": updavleft + "px"} }).append(months[i].substr(0, 7)));
                            updavleft = updavleft + monthwidth + 1;
                        }

                        break;
                    //按月
                    case 'month':
                        break;
                    //按天
                    default:
                        var months = [];
                        var date = startdate;
                        while (DateMethod.StringToDate(date.substr(0, 7) + '-01') <= DateMethod.StringToDate(enddate.substr(0, 7) + '-01')) {
                            months.push(date);
                            date = DateMethod.format(DateMethod.DateAdd(DateMethod.StringToDate(date), 'm', 1), "YYYY-MM-DD");
                        }
                        //甘特图的列数
                        var headcolumcount = 0;
                        for (var i = 0; i < months.length; i++) {
                            //生产甘特图表头第一行
                            var daycount = DateMethod.getDays(months[i].substr(0, 4), months[i].substr(5, 2));
                            upDiv.append(jQuery("<div>", { "class": "GantChatHeaderDiv_cell", "css": { "width": (daycount * (cellWidth + 1) - 1) + "px", "height": cellheight + "px", "left": headcolumcount * (cellWidth + 1) + "px"} }).append(months[i].substr(0, 7)));
                            for (var m = 1; m <= daycount; m++) {
                                //生产甘特图表头第二行

                                var day = m <= 9 ? '0' + m : m;
                                var datecell = months[i].substr(0, 7) + "-" + day;

                                var week = DateMethod.GetWeekIndex(datecell);

                                downDiv.append(jQuery("<div>", { "class": "GantChatHeaderDiv_cell", "css": { "width": cellWidth + "px", "height": cellheight + "px", "left": headcolumcount * (cellWidth + 1) + "px"} }).append(m));

                                var dayclass = "GantChatBodyDiv_colnum";
                                if (DateMethod.isWeekend(DateMethod.StringToDate(datecell))) {
                                    dayclass = "GantChatBodyDiv_colnum_weekend"
                                }
                                gantbody.append(jQuery("<div>", { "class": dayclass, "id": "GantChatBodyDiv_colnum" + datecell, "css": { "width": cellWidth + "px", "height": (cellheight + 1) * rowcount - 1 + "px", "left": headcolumcount * (cellWidth + 1) + "px"} }));
                                headcolumcount = headcolumcount + 1;
                            }
                        }
                        break;
                };

                //设置上下表头的宽度
                upDiv.css({ width: headcolumcount * (cellWidth + 1) + "px" });
                downDiv.css({ width: headcolumcount * (cellWidth + 1) + "px" });
                //生成甘特图中显示任务的行
                for (var i = 0; i < tasks.length; i++) {
                    gantbody.append(jQuery("<div>", { "id": "GantChatBodyDiv_row" + tasks[i].taskid, "class": "GantChatBodyDiv_row", "css": { "width": headcolumcount * (cellWidth + 1) + "px", "height": cellheight + "px"} }).data("taskdata", tasks[i]));
                }
                gantbody.css({ "top": cellheight * 2 + 2 + "px", "width": headcolumcount * (cellWidth + 1) + "px", "height": gantHeight - cellheight * 2 + 12 + "px" });

                //添加任务条
                $(".GantChatBodyDiv_row", gantbody).each(function (i) {
                    var tasktop = 4;
                    var taskheight = cellheight - 2 * tasktop;
                    var Ptaskleft = TaskMethod.getLeft(tasks[i].taskPSdate, chattype, "start");
                    var Ptaskright = TaskMethod.getLeft(tasks[i].taskPEdate, chattype);
                    var Ptaskwidth = Ptaskright - Ptaskleft + cellWidth;
                    $(this).append(jQuery("<div>", { "class": "GantChatBody_PlanTask", "css": { "width": Ptaskwidth - 1 + "px", "height": taskheight + "px", "left": Ptaskleft - 1 + "px", "top": tasktop - 1 + "px"} }).append(tasks[i].taskname));
                    if (tasks[i].taskASdate != "" && tasks[i].taskAEdate != "") {
                        var Ataskleft = TaskMethod.getLeft(tasks[i].taskASdate, chattype, "start");
                        var Ataskright = TaskMethod.getLeft(tasks[i].taskAEdate, chattype);
                        var Ataskwidth = Ataskright - Ataskleft + cellWidth;
                        $(this).append(jQuery("<div>", { "class": TaskMethod.getATaskClass(tasks[i]), "css": { "width": Ataskwidth + "px", "height": taskheight + "px", "left": Ataskleft + "px", "top": tasktop + "px"} }));
                    }
                });

                //添加任务的提示功能
                if (options.usetip) {
                    $(".GantChatBody_PlanTask,.GantChatBody_ActulTask", gantbody).mouseover(function (e) {
                        var task = $(this).parent().data("taskdata");
                        var tiptext = "";
                        var worddec = task.taskid.indexOf("W") > 0 && task.meno != "" ? "工作名称" : "项目名称";
                        tiptext = "<B>" + worddec + "：</B>" + task.meno + "<br/><B>任务名称：</B>" + task.taskname + "<br/><B>计划开始时间：</B>" + task.taskPSdate + "<br/><B>计划结束时间：</B>" + task.taskPEdate + "<br/><B>实际开始时间：</B>" + task.taskASdate + "<br/><B>实际结束时间：</B>" + task.taskAEdate;
                        var tip = $("<div class='YanGantHov' />").html(tiptext);
                        $("body").append(tip);
                        tip.css('left', e.pageX);
                        tip.css('top', e.pageY);
                        tip.show();
                    }).mouseout(function () {
                        $(".YanGantHov").remove();
                    }).mousemove(function (e) {
                        $('.YanGantHov').css('left', e.pageX);
                        $('.YanGantHov').css('top', e.pageY + 15);
                    });
                };
                gantobj.append(upDiv).append(downDiv).append(gantbody);
            }
        };

        var YanTableMethod = {
            addTable: function (tasks) {
                var colmModel = options.colmModel;
                var cellheight = options.cellheight;
                var gantHeight = options.gantHeight * 1;

                //生成数据表格的头部
                var tableheader = jQuery("<div>", { "class": "GantDataHeaderDiv", "css": { "height": cellheight * 2 + 1 + "px"} });
                var headerleft = 0;
                for (var i = 0; i < colmModel.length; i++) {
                    tableheader.append(jQuery("<div>", { "class": "GantDataHeader_cell", "css": { "width": colmModel[i].width + "px", "height": cellheight * 2 + 1 + "px", "left": headerleft + "px"} }).append(colmModel[i].display));
                    headerleft = headerleft + colmModel[i].width * 1 + 1;
                }
                tableheader.css({ "width": headerleft + "px" });
                gantabletobj.append(tableheader);
                //生成数据表格的头部

                //生成数据表格的内容
                var tablecontent = jQuery("<div>", { "id": "YandataContent", "class": "YandataContent", "css": { "width": headerleft + "px", "height": gantHeight - cellheight * 2 + 12 * 1 + "px", "top": cellheight * 2 + 2 + "px"} });
                var datacelltop = 0;
                for (var m = 0; m < tasks.length; m++) {
                    var dataleft = 0;
                    var tabledata = jQuery("<div>", { "id": "GantDataDiv" + tasks[m].taskid, "class": "GantDataDiv", "isexp": "y", "css": { "height": cellheight + "px"} }).data("task", tasks[m]);

                    for (var i = 0; i < colmModel.length; i++) {
                        var GantData_cell = jQuery("<div>", { "class": "GantData_cell", "css": { "width": colmModel[i].width + "px", "line-height": cellheight + "px", "height": cellheight + "px", "left": dataleft + "px"} });
                        var divcontent = tasks[m][colmModel[i].name];
                        //如果是第一列，将第一列内容居左对齐，并加上图片
                        //如果是任务执行者的一列，则将长度大于五的用省略号代替
                        if (colmModel[i].name == "taskname") {
                            GantData_cell.append("&nbsp;").css({ "text-align": "left" });
                            //生成空格
                            var space = new Array((tasks[m].tasklev * 1) * 4).join("&nbsp;");
                            tabledata.append(GantData_cell.append(space + "&nbsp;&nbsp;<img class='img' src='" + options.open_img + "'>&nbsp;&nbsp;" + divcontent)).css({ "cursor": "pointer" });
                        }
                        else if (colmModel[i].name == "taskuser" && divcontent.length > 5) {
                            divcontent = divcontent.substring(0, 5) + "...";
                            tabledata.append(GantData_cell.append(divcontent));
                        }
                        else {
                            tabledata.append(GantData_cell.append(divcontent));
                        }
                        dataleft = dataleft + colmModel[i].width * 1 + 1;
                    }
                    tabledata.css({ "width": dataleft + "px" });
                    datacelltop = datacelltop + cellheight * 1 + 1;
                    tablecontent.append(tabledata);
                }
                gantabletobj.append(tablecontent);

                //添加拖动改变大小的DIV
                var gantdrag = jQuery("<div>", { "id": "YanDataDrag", "class": "YanDataDrag", "css": { "height": gantHeight + 30 - 17 + "px"} });
                gantdrag.dblclick(function () {
                    var graglen = 10;
                    var nowwidth = gantabletobj.width();
                    if (nowwidth <= graglen) {
                        $("#YanGant", thisTable).animate({ "left": options.tablewidth + "px", "width": $("#YanGant", thisTable).width() - options.tablewidth + graglen + "px" });
                        gantabletobj.animate({ "width": options.tablewidth });
                        gantdrag.css({ "background-color": "" });
                    }
                    else {
                        var chengw = gantabletobj.width() - graglen;
                        gantabletobj.animate({ "width": "10px" });
                        $("#YanGant", thisTable).animate({ "left": "10px", "width": $("#YanGant", thisTable).width() + chengw + "px" });
                        gantdrag.css({ "background-color": "#F3F8FF" });
                    }
                })
                gantabletobj.append(gantdrag);

                //添加数据部分的拖动功能
                this.binddrag(gantabletobj);
                gantabletobj.scroll(function () {
                    gantdrag.css({ "right": -$(this).scrollLeft() + "px" });
                });
            },
            closeChild: function (ptask) {
                //获取子任务,如果包含子项，则改变图标,并赋予展开属性
                var select = "";
                var arrchildtask = ptask.data("task").arrchild;
                if (arrchildtask.length > 0) {
                    ptask.attr("isexp", "n").find(".img").attr("src", options.close_img);
                }
                var childlength = arrchildtask.length;
                for (var i = 0; i < arrchildtask.length; i++) {
                    var tasknow = $("#GantDataDiv" + arrchildtask[i], gantabletobj);
                    if (!tasknow.is(":hidden")) {
                        select = select + "#GantChatBodyDiv_row" + arrchildtask[i] + ",#GantDataDiv" + arrchildtask[i];
                        if (i != arrchildtask.length - 1) {
                            select = select + ","
                        }
                    }
                    else {
                        childlength = childlength - 1;
                    }
                }
                var lastIndex = select.lastIndexOf(',');
                if (select.length-1 === lastIndex) {
                    select = select.substring(0, lastIndex);
                }
                $(select).css({ "display": "none" });
                //更改甘特图中时间条的高度
                var colnumheight = $(".GantChatBodyDiv_colnum", gantobj).eq(0).height();
                $(".GantChatBodyDiv_colnum ,.GantChatBodyDiv_colnum_weekend", gantobj).height(colnumheight - (options.cellheight * 1 + 1) * childlength);
                $(".YanGant_ScrollC", gantscroll).height(colnumheight - (options.cellheight * 1 + 1) * childlength);
            },
            expandChild: function (ptask) {
                var select = "";
                //获取子任务,如果包含子项，则改变图标,并赋予展开属性
                var arrchildtask = ptask.data("task").arrchild;
                var childlength = arrchildtask.length;

                if (childlength > 0) {
                    ptask.attr("isexp", "y").find(".img").attr("src", options.open_img);
                }
                //定义等待折叠的任务数组
                var arrholdexptask = new Array();

                for (var i = 0; i < childlength; i++) {
                    var tasknow = $("#GantDataDiv" + arrchildtask[i], gantabletobj);

                    select = select + "#GantChatBodyDiv_row" + arrchildtask[i] + ",#GantDataDiv" + arrchildtask[i];
                    if (i != childlength - 1) {
                        select = select + ","
                    }
                    if (tasknow.attr("isexp") == "n") {
                        arrholdexptask.push(tasknow);
                        tasknow.attr("isexp", "y").find(".img").attr("src", options.open_img);
                    }
                }
                var lastIndex = select.lastIndexOf(',');
                if (select.length-1 === lastIndex) {
                    select = select.substring(0, lastIndex);
                }
                $(select).css({ "display": "block" });

                //更改甘特图中时间条的高度
                var colnumheight = $(".GantChatBodyDiv_colnum", gantobj).eq(0).height();
                $(".GantChatBodyDiv_colnum ,.GantChatBodyDiv_colnum_weekend", gantobj).height(colnumheight * 1 + (options.cellheight * 1 + 1) * childlength);
                $(".YanGant_ScrollC", gantscroll).height(colnumheight * 1 + (options.cellheight * 1 + 1) * childlength);
                //折叠等待折叠数组内需要折叠的任务
                for (var i = 0; i < arrholdexptask.length; i++) {
                    this.closeChild(arrholdexptask[i]);
                }
            },
            //根据节点级别展开节点
            expnode: function (nodelev) {
                //先将所有节点展开
                $(".GantDataDiv", gantabletobj).each(function () {
                    if ($(this).attr("isexp") != "y") {
                        YanTableMethod.expandChild($(this));
                    }
                });
                //在将需要折叠的节点折叠
                $(".GantDataDiv", gantabletobj).each(function () {
                    if ($(this).data("task").tasklev == nodelev * 1) {
                        YanTableMethod.closeChild($(this));
                    }
                });
            },
            changewl: function (w, h) {
                $("#YandataContent,#Yandata", thisTable).each(function () {
                    var heightnow = parseInt($(this).css("height"));
                    var widthnow = parseInt($(this).css("width"));
                    $(this).width(widthnow + w * 1).height(heightnow + h * 1);
                })
            },
            binddrag: function (e) {
                e.resizable({
                    handler: '#YanDataDrag',
                    min: { width: 10, height: e.height() },
                    max: { width: $("#YandataContent", e).width(), height: e.height() },
                    onResize: function (e) {
                        waitToggle(thisTable, true);
                    },
                    onStop: function (e) {
                        var oldtabwidth = $("#YanGant", thisTable).css('width');
                        var oldgantleft = $("#YanGant", thisTable).css('left');
                        var changew = parseInt(e.data.resizeData.target.css('width')) - e.data.resizeData.width;
                        $("#YanGant", thisTable).css({ "left": parseInt(oldgantleft) + changew, "width": parseInt(oldtabwidth) - changew });
                        waitToggle(thisTable, false)
                    }
                });
            }
        };

        this.each(function (Yancount) {
            thisTable.empty();
            thisTable.css({ "width": options.tablewidth * 1 + 1 + options.gantWidth * 1 + "px", "height": options.gantHeight * 1 + 41 + 30 + "px" }).addClass("dvYanGant");
            if (options.data) {
                waitToggle(thisTable, true, function () {
                    options.startdate = options.data.startdate;
                    options.enddate = options.data.enddate;

                    //处理任务数据
                    var tasks = YanGantMethod.managerData(options.data);

                    //甘特图标题栏
                    var ganttitleobj = jQuery("<div>", { "id": "YanTitle", "class": "YanTitle", "css": { "height": "40px", "width": options.tablewidth * 1 + options.gantWidth * 1 + 1 + "px" } }).append("<div  class='YanTitleFont'>" + options.title + "</div>").append("<div class='YanTitleTL'></div>");

                    //甘特图数据表格
                    gantabletobj = jQuery("<div>", { "id": "Yandata", "class": "Yandata", "css": { "height": options.gantHeight * 1 + 30 + "px", "width": options.tablewidth + "px", "top": "40px" } });
                    YanTableMethod.addTable(tasks);

                    //甘特图框架，+30是为了让滚动条内的内容全部看得见
                    gantobj = jQuery("<div>", { "id": "YanGant", "class": "YanGant", "css": { "width": options.gantWidth + "px", "left": options.tablewidth + "px", "height": options.gantHeight * 1 + 30 + "px", "top": "40px" } });
                    YanGantMethod.addGantBody(options.chattype, tasks);

                    //模拟滚动条
                    var scrollheight = $(".GantChatBodyDiv_colnum", gantobj).eq(0).height();
                    gantscroll = jQuery("<div>", { "id": "YanGantScroll", "class": "YanGant_ScrollP", "css": { "left": options.gantWidth - 17 + options.tablewidth * 1 + 1 + "px", "top": options.cellheight * 2 + 43 + "px", "height": options.gantHeight - options.cellheight * 2 + 12 + "px" } }).append("<div class='YanGant_ScrollC' style='height:" + scrollheight + "px' ></div>");
                    //竖向滚动条事件
                    gantscroll.scroll(function () {
                        var s = gantscroll.scrollTop();
                        $(".YandataContent", gantabletobj).scrollTop(s);
                        gantbody.scrollTop(s);
                    });

                    //生成整个Gant表样式
                    thisTable.prepend(gantscroll).prepend(gantobj).prepend(gantabletobj).prepend(ganttitleobj).data("tasks", tasks);

                    //点击父项目事件
                    $(".GantDataDiv", gantabletobj).click(function () {
                        var dom = $(this);
                        if (dom.attr("isexp") == "y") {
                            YanTableMethod.closeChild(dom);
                        }
                        else {
                            YanTableMethod.expandChild(dom);
                        }

                        //添加定位功能
                        if (options.isfixposition) {
                            var taskid = $(this).data("task").taskid;
                            var left = $(".GantChatBody_PlanTask", $("#GantChatBodyDiv_row" + taskid)).css("left");
                            left = left.substr(0, left.length - 2);
                            $("#YanGant").animate({ scrollLeft: left > 20 ? left - 20 : left + 'px' }, "normal");
                        }
                    });

                    //添加拖动改变大小事件
                    if (options.isResizable) {
                        thisTable.append('<div id="Yan-handler" class="Yan-handler"></div>');
                        thisTable.resizable({
                            handler: '#Yan-handler',
                            min: { width: options.tablewidth * 1 + options.gantWidth * 1 + 1, height: options.gantHeight * 1 + 41 },
                            max: { width: 1500, height: 1500 },
                            onResize: function (e) {
                                waitToggle(thisTable, true);
                            },
                            onStop: function (e) {
                                var changew = parseInt(e.data.resizeData.target.css('width')) - e.data.resizeData.width;
                                var changeh = parseInt(e.data.resizeData.target.css('height')) - e.data.resizeData.height;
                                YanTableMethod.changewl(0, changeh);
                                YanGantMethod.changewl(changew, changeh);
                                var YanGantScroll = $("#YanGantScroll", thisTable);
                                YanGantScroll.height(parseInt(YanGantScroll.height()) + changeh).css({ "left": parseInt(YanGantScroll.css("left")) + changew });

                                //改变table拖动条的高度
                                $("#YanDataDrag", thisTable).height(changeh + $("#YanDataDrag", thisTable).height())
                                //重新绑定table的拖动事件
                                YanTableMethod.binddrag(gantabletobj);

                                waitToggle(thisTable, false)
                            }
                        });
                    }
                    //添加鼠标移入事件
                    $(".GantChatBodyDiv_row,.GantDataDiv", thisTable).hover(
                        function () {
                            var taskid = $(this).attr("id").replace("GantDataDiv", "").replace("GantChatBodyDiv_row", "");
                            $("#GantDataDiv" + taskid, thisTable).add($("#GantChatBodyDiv_row" + taskid, thisTable)).addClass("GantRowhov");
                        },
                        function () {
                            var taskid = $(this).attr("id").replace("GantDataDiv", "").replace("GantChatBodyDiv_row", "");
                            $("#GantDataDiv" + taskid, thisTable).add($("#GantChatBodyDiv_row" + taskid, thisTable)).removeClass("GantRowhov");
                        }
                     );

                    //展开级别为一的节点
                    if ($.browser.version != "7.0") {
                        YanTableMethod.expnode(options.expandlev);
                    }

                    waitToggle(thisTable, false);
                });

            }
        });
        thisTable.data("option", options).data("YanGantMethod", YanGantMethod).data("YanTableMethod", YanTableMethod).fadeIn('normal');
    };

    //切换周，天显示
    $.fn.YanChangeInterval = function (intervaltype) {
        var option = $(this).data("option");
        if (option) {
            option.chattype = intervaltype;
            $(this).YanGant(option);
        }
    }
    //按级别展开节点
    $.fn.YanExpnodel = function (nodevel) {
        var funTab = $(this).data("YanTableMethod");
        if (funTab) {
            funTab.expnode(nodevel);
        }
    }

    //拖动功能
    $.fn.resizable = function (opts) {
        var ps = $.extend({
            handler: null,
            min: { width: 0, height: 0 },
            max: { width: $(document).width(), height: $(document).height() },
            onResize: function () { },
            onStop: function () { }
        }, opts);
        var resize = {
            resize: function (e) {
                var resizeData = e.data.resizeData;

                var w = Math.min(Math.max(e.pageX - resizeData.offLeft + resizeData.width, resizeData.min.width), ps.max.width);
                var h = Math.min(Math.max(e.pageY - resizeData.offTop + resizeData.height, resizeData.min.height), ps.max.height);
                resizeData.target.css({
                    width: w,
                    height: h
                });
                resizeData.onResize(e);
            },
            stop: function (e) {
                e.data.resizeData.onStop(e);

                document.body.onselectstart = function () { return true; }
                e.data.resizeData.target.css('-moz-user-select', '');

                $(document).unbind('mousemove', resize.resize)
                    .unbind('mouseup', resize.stop);
            }
        }
        return this.each(function () {
            var me = this;
            var handler = null;
            if (typeof ps.handler == 'undefined' || ps.handler == null) {
                handler = $(me);
            }
            else {
                handler = (typeof ps.handler == 'string' ? $(ps.handler, this) : ps.handle);

                //清除绑定的事件
                handler.unbind("mousedown");
                $(document).unbind("mousemove", resize.resize).unbind("mouseup", resize.stop);

                handler.bind('mousedown', { e: me }, function (s) {
                    var target = $(s.data.e);
                    var resizeData = {
                        width: target.width(),
                        height: target.height(),
                        offLeft: s.pageX,
                        offTop: s.pageY,
                        onResize: ps.onResize,
                        onStop: ps.onStop,
                        target: target,
                        min: ps.min,
                        max: ps.max
                    }

                    document.body.onselectstart = function () { return false; }
                    target.css('-moz-user-select', 'none');

                    $(document).bind('mousemove', { resizeData: resizeData }, resize.resize)
                    .bind('mouseup', { resizeData: resizeData }, resize.stop);
                });
            }
        });
    }
})(jQuery);